package com.qire.manhua.view.refresh;


import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.qire.common.utils.EquipmentInfoUtil;
import com.qire.manhua.view.drawable.MaterialProgressDrawable;
import com.scwang.smart.drawable.ProgressDrawable;
import com.scwang.smart.refresh.layout.api.RefreshHeader;
import com.scwang.smart.refresh.layout.api.RefreshKernel;
import com.scwang.smart.refresh.layout.api.RefreshLayout;
import com.scwang.smart.refresh.layout.constant.RefreshState;
import com.scwang.smart.refresh.layout.constant.SpinnerStyle;

import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

import static android.view.View.MeasureSpec.AT_MOST;
import static android.view.View.MeasureSpec.EXACTLY;
import static android.view.View.MeasureSpec.getSize;
import static android.view.View.MeasureSpec.makeMeasureSpec;
import static android.widget.ListPopupWindow.MATCH_PARENT;
import static android.widget.ListPopupWindow.WRAP_CONTENT;
import static com.scwang.smart.refresh.layout.constant.RefreshState.RefreshFinish;
import static com.scwang.smart.refresh.layout.constant.RefreshState.RefreshReleased;
import static com.scwang.smart.refresh.layout.constant.RefreshState.Refreshing;
import static com.scwang.smart.refresh.layout.constant.RefreshState.ReleaseToRefresh;

public class ColorWaterDropHeader extends ViewGroup implements RefreshHeader {

    //<editor-fold desc="Field">
    private static final float MAX_PROGRESS_ANGLE = 0.8f;

    private boolean isDropDone = false;
    private final static float dropDownThreshold = 1.9f;

    // 默认白色，有个例外就是我的页面水滴是白色的所以水滴中的进度指示器不能用白色的了 比如 0xffffd642
    private int progressColor = 0xffffffff;

    private RefreshState mState;
    private ImageView mImageView;
    private TextView mTextView;
    private WaterDropView mWaterDropView;
    private ProgressDrawable mProgressDrawable;
    private MaterialProgressDrawable mProgress;
    private int mProgressDegree = 0;
    private int ropDownDistance=0;
    //</editor-fold>


    public void setProgressColor(int progressColor) {
        this.progressColor = progressColor;
        mProgress.setColorSchemeColors(progressColor);
    }

    public void setProgressDrawableColor(int color){
        this.mProgressDrawable.setColor(color);
        this.setTextViewColor(color);
    }

    public void setTextViewColor(int color){
        this.mTextView.setTextColor(color);
    }

    //<editor-fold desc="ViewGroup">
    public ColorWaterDropHeader(Context context) {
        super(context);
        this.initView(context);
    }

    public ColorWaterDropHeader(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.initView(context);
    }

    public ColorWaterDropHeader(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.initView(context);
    }

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    public ColorWaterDropHeader(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        this.initView(context);
    }

    private void initView(Context context) {
        mWaterDropView = new WaterDropView(context);
        addView(mWaterDropView, MATCH_PARENT, MATCH_PARENT);
        mWaterDropView.updateCompleteState(0);

        mProgressDrawable = new ProgressDrawable();
        mProgressDrawable.setBounds(0, 0, EquipmentInfoUtil.dip2px(15), EquipmentInfoUtil.dip2px(15));
        mProgressDrawable.setCallback(this);

        mImageView = new ImageView(context);
        mProgress = new MaterialProgressDrawable(context, mImageView);
        mProgress.setBackgroundColor(progressColor);
        mProgress.setAlpha(255);
        mProgress.setColorSchemeColors(progressColor,0xff0099cc,0xffff4444,0xff669900,0xffaa66cc,0xffff8800);
        mImageView.setImageDrawable(mProgress);
        addView(mImageView, EquipmentInfoUtil.dip2px(30), EquipmentInfoUtil.dip2px(30));

        mTextView = new TextView(context);
        LayoutParams layoutParams = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
        addView(mTextView, layoutParams);

        mTextView.setText("正在加载");
        mTextView.setTextColor(0xff888888);
        mTextView.setVisibility(INVISIBLE);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        ViewGroup.LayoutParams lpImage = mImageView.getLayoutParams();
        mImageView.measure(
                makeMeasureSpec(lpImage.width, EXACTLY),
                makeMeasureSpec(lpImage.height, EXACTLY)
        );
        mWaterDropView.measure(
                makeMeasureSpec(getSize(widthMeasureSpec), AT_MOST),
                heightMeasureSpec
        );

        measureChild(mTextView, widthMeasureSpec, heightMeasureSpec);

        /*LayoutParams lp = mTextView.getLayoutParams();
        int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec,0,lp.width);
        int childHeightSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec,0,lp.height);
        mTextView.measure(childWidthSpec, childHeightSpec);*/

        int maxWidth = Math.max(mImageView.getMeasuredWidth(), mWaterDropView.getMeasuredHeight());
        int maxHeight = Math.max(mImageView.getMeasuredHeight(), mWaterDropView.getMeasuredHeight());
        setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec), resolveSize(maxHeight, heightMeasureSpec));
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int measuredWidth = getMeasuredWidth();

        final int widthWaterDrop = mWaterDropView.getMeasuredWidth();
        final int heightWaterDrop = mWaterDropView.getMeasuredHeight();
        final int leftWaterDrop = measuredWidth / 2 - widthWaterDrop / 2;
        final int topWaterDrop = 0;
        mWaterDropView.layout(leftWaterDrop, topWaterDrop, leftWaterDrop + widthWaterDrop, topWaterDrop + heightWaterDrop);

        final int widthImage = mImageView.getMeasuredWidth();
        final int heightImage = mImageView.getMeasuredHeight();
        final int leftImage = measuredWidth / 2 - widthImage / 2;
        int topImage = widthWaterDrop / 2 - widthImage / 2;
        if (topImage + heightImage > mWaterDropView.getBottom() - (widthWaterDrop - widthImage) / 2) {
            topImage = mWaterDropView.getBottom() - (widthWaterDrop - widthImage) / 2 - heightImage;
        }
        mImageView.layout(leftImage, topImage, leftImage + widthImage, topImage + heightImage);

        final int widthTextView = mTextView.getMeasuredWidth();
        final int heightTextView = mTextView.getMeasuredHeight();
        final int leftTextView = measuredWidth / 2 - widthTextView / 2;
        final int topTextView = getMeasuredHeight() / 2 - heightTextView / 2;
        mTextView.layout(leftTextView,  topTextView , leftTextView + widthTextView, topTextView + heightTextView);
    }
    //</editor-fold>

    //<editor-fold desc="Draw">
    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        if (mState == Refreshing) {
            canvas.save();
            canvas.translate(
                    getWidth()/2-mProgressDrawable.getBounds().width()/2,
                    getMeasuredHeight()/2 - mProgressDrawable.getBounds().height()/2);
            mProgressDrawable.draw(canvas);
            canvas.restore();
        }
    }

    @Override
    public void invalidateDrawable(@NonNull Drawable drawable) {
        if (drawable == mProgressDrawable) {
            invalidate();
        } else {
            super.invalidateDrawable(drawable);
        }
    }
    //</editor-fold>

    //<editor-fold desc="RefreshHeader">
    @Override
    public void onInitialized(@NonNull RefreshKernel kernel, int height, int extendHeight) {
//        System.out.println("onInitialized");
    }

    @Override
    public boolean isSupportHorizontalDrag() {
        return false;
    }

    @Override
    public void onHorizontalDrag(float percentX, int offsetX, int offsetMax) {
    }

    @Override
    public void onMoving(boolean isDragging, float percent, int offset, int height, int maxDragHeight) {
        if(isDragging) {
            onPulling(percent, offset, height, maxDragHeight);
        } else {
            onReleasing(percent, offset, height, maxDragHeight);
        }
    }

    private void onPulling(float percent, int offset, int height, int extendHeight) {
        ropDownDistance = offset;
//        System.out.println("percent + " + percent);

        //拉过指定值中断水滴下拉进行回弹
        if(!isDropDone && percent > dropDownThreshold){
            mProgressDrawable.start();
            mImageView.setVisibility(GONE);
            mWaterDropView.setVisibility(GONE);
            /*mWaterDropView.createAnimator().start();//开始回弹
            mWaterDropView.animate().alpha(0).setListener(new AnimatorListenerAdapter() {
                public void onAnimationEnd(Animator animation) {
                    mWaterDropView.setVisibility(GONE);
                    mWaterDropView.setAlpha(1);
                }
            });*/
            mState = Refreshing;
            isDropDone = true;
        }

        if(isDropDone){
            return;
        }

        mWaterDropView.updateCompleteState((offset), height + extendHeight);
        mWaterDropView.postInvalidate();

        float originalDragPercent = 1f * offset / height;

        float dragPercent = Math.min(1f, Math.abs(originalDragPercent));
        float adjustedPercent = (float) Math.max(dragPercent - .4, 0) * 5 / 3;
        float extraOS = Math.abs(offset) - height;
        float tensionSlingshotPercent = Math.max(0, Math.min(extraOS, (float) height * 2)
                / (float) height);
        float tensionPercent = (float) ((tensionSlingshotPercent / 4) - Math.pow(
                (tensionSlingshotPercent / 4), 2)) * 2f;
        float strokeStart = adjustedPercent * .8f;
        float rotation = (-0.25f + .4f * adjustedPercent + tensionPercent * 2) * .5f;
        mProgress.showArrow(true);
        mProgress.setStartEndTrim(0f, Math.min(MAX_PROGRESS_ANGLE, strokeStart));
        mProgress.setArrowScale(Math.min(1f, adjustedPercent));
        mProgress.setProgressRotation(rotation);

    }

    private void onReleasing(float percent, int offset, int height, int extendHeight) {
        ropDownDistance = offset;
        if(isDropDone){
            return;
        }

        if (mState != Refreshing && mState != RefreshReleased) {
            mWaterDropView.updateCompleteState(Math.max(offset, 0), height + extendHeight);
            mWaterDropView.postInvalidate();
        }
    }

    @Override
    public void onReleased(final RefreshLayout layout, int height, int extendHeight) {

        if(isDropDone){
            return;
        }
        mProgressDrawable.start();
        mWaterDropView.createAnimator().start();//开始回弹
        mWaterDropView.animate().alpha(0).setListener(new AnimatorListenerAdapter() {
            public void onAnimationEnd(Animator animation) {
                mWaterDropView.setVisibility(GONE);
                mWaterDropView.setAlpha(1);
            }
        });
    }

    @Override
    public void onStartAnimator(@NonNull RefreshLayout layout, int height, int extendHeight) {

    }

    @Override
    public int onFinish(@NonNull RefreshLayout layout, boolean success) {

        mState = RefreshFinish;

        mTextView.setVisibility(VISIBLE);
        if(success){
            mTextView.setText("加载完成");
        } else {
            mTextView.setText("加载失败");
        }
        mProgressDrawable.stop();
        isDropDone = false;
        return 500;
    }

    /**
     * @param colors 对应Xml中配置的 srlPrimaryColor srlAccentColor
     * @deprecated 请使用 {@link RefreshLayout#setPrimaryColorsId(int...)}
     */
    @Override
    @Deprecated
    public void setPrimaryColors(@ColorInt int ... colors) {
        if (colors.length > 0) {
            mWaterDropView.setIndicatorColor(colors[0]);
        }
    }

    @NonNull
    @Override
    public View getView() {
        return this;
    }

    @NonNull
    @Override
    public SpinnerStyle getSpinnerStyle() {
        return SpinnerStyle.Scale;
    }

    //</editor-fold>
    @Override
    public void onStateChanged(RefreshLayout refreshLayout, RefreshState oldState, RefreshState newState) {

        if(mState == Refreshing){
            if(newState == ReleaseToRefresh || newState == RefreshFinish || newState == RefreshReleased)
                return;
        }

        mState = newState;
        switch (newState) {
            case None:
                mImageView.setVisibility(View.VISIBLE);
                mTextView.setVisibility(View.INVISIBLE);
                mWaterDropView.setVisibility(View.VISIBLE);
                break;
            case PullDownToRefresh:
                mTextView.setVisibility(View.INVISIBLE);
                mWaterDropView.setVisibility(View.VISIBLE);
                break;
            case PullDownCanceled:
                isDropDone = false;
                break;
            case ReleaseToRefresh:
                mWaterDropView.setVisibility(View.VISIBLE);
                break;
            case Refreshing:
                break;
            case RefreshFinish:
                mWaterDropView.setVisibility(View.GONE);
                break;
        }
    }

//    @Override
//    public int getDropDownDistance() {
//        return ropDownDistance;
//    }



}